package com.azh.server.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.cert.CertSelector;

import com.azh.server.tables.TableManager;
import com.azh.server.transport.APackger;
import com.azh.server.transport.Encoder;
import com.azh.server.transport.Package;
import com.azh.server.transport.Transporter;
import com.azh.server.util.ExceptionUtils;

/**
 * @author zhaozhenhang <zhaozhenhang@kuaishou.com>
 * Created on 2022-05-02
 * SocketHandeler 实现Runnable接口，建立链接后初始化APackger
 * 然后循环接收来自客服端的数据并处理
 */
public class SocketHandeler implements Runnable {

    private Socket socket;
    private TableManager tm;

    public SocketHandeler(Socket socket, TableManager tm) {
        this.socket = socket;
        this.tm = tm;
    }


    @Override
    public void run() {
        InetSocketAddress address = (InetSocketAddress) socket.getRemoteSocketAddress();
        APackger aPackger = null;
        try {
            Transporter t = new Transporter(socket);
            Encoder e = new Encoder();
            aPackger = new APackger(t, e);
        } catch (IOException e) {
            ExceptionUtils.getMessage(e);
            try {
                socket.close();
            } catch (IOException exception) {
                ExceptionUtils.getMessage(e);
            }
        }
        Executor executor = new Executor(tm);
        for (; ; ) {
            Package pkg = null;
            try {
                pkg = aPackger.receive();
            } catch (Exception e) {
                break;
            }
            byte[] sql = pkg.getData();
            byte[] result = null;
            Exception err = null;
            try {
                result = executor.execute(sql);
            } catch (Exception e) {
                err = e;
                ExceptionUtils.getMessage(e);
            }
            pkg = new Package(result, err);
            try {
                aPackger.send(pkg);
            } catch (Exception e) {
                ExceptionUtils.getMessage(e);
                break;
            }
        }
        executor.close();
        try {
            aPackger.close();
        } catch (Exception e) {
            ExceptionUtils.getMessage(e);
        }
    }
}
